<template>
  <div class="cool-image-upload">
    <!-- 图片上传区域 -->
    <div class="upload-container">
      <div class="image-list" v-if="previewImages.length">
        <div
          v-for="(image, index) in previewImages"
          :key="index"
          class="image-item"
        >
          <img :src="image" class="preview-image" />
          <div class="image-actions">
            <div class="action-btn view-btn" @click="previewImage(image)">
              <span class="iconfont icon-beijing_post_info"></span>
            </div>
            <div class="action-btn delete-btn" @click="removeImage(index)">
              <span class="iconfont icon-shanchu11"></span>
            </div>
          </div>
        </div>

        <!-- 多图上传时的添加按钮 -->
        <div
          v-if="multiple && previewImages.length < maxCount"
          class="image-item add-more"
          @click="triggerUpload"
        >
          <div class="add-icon iconfont icon-shangchuan1"></div>
          <div class="add-text">上传图片</div>
        </div>
      </div>

      <!-- 无图片时的上传区域 -->
      <div
        v-if="previewImages.length === 0"
        class="upload-area"
        @click="triggerUpload"
      >
        <span class="iconfont icon-tupian icon-shangchuan1"></span>
        <div class="upload-text">
          <div>点击或拖拽图片上传</div>
          <div class="upload-tip">
            {{ multiple ? `最多上传${maxCount}张图片` : "请上传一张图片" }}
          </div>
        </div>
      </div>
    </div>

    <!-- 文件选择器 -->
    <input
      ref="fileInput"
      type="file"
      :accept="accept"
      :multiple="multiple"
      @change="handleFileChange"
      style="display: none"
    />

    <!-- 图片预览对话框 -->
    <cool-dialog v-model="previewVisible" title="图片预览" :showFooter="false">
      <div class="preview-container">
        <img :src="previewUrl" class="preview-large-image" />
      </div>
    </cool-dialog>
  </div>
</template>

<script>
import { uploadFile } from "@/http/upfile";
import CoolDialog from "@/components/CoolDialog.vue";
import { ElMessage, ElLoading } from "element-plus";

export default {
  name: "CoolImageUpload",
  components: {
    CoolDialog,
  },
  props: {
    // 是否多图上传
    multiple: {
      type: Boolean,
      default: false,
    },
    // 接受的文件类型
    accept: {
      type: String,
      default: "image/jpeg,image/png,image/jpg,image/gif",
    },
    // 最大上传数量
    maxCount: {
      type: Number,
      default: 5,
    },
    // 图片上传路径
    uploadUrl: {
      type: String,
      default: "/common/Upload/UpFile",
    },
    // 已有图片地址(单张为字符串，多张为逗号分隔的字符串)
    value: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      previewImages: [], // 预览图片列表
      uploadedUrls: [], // 已上传的图片URL列表
      fileInput: null, // 文件输入引用
      loading: false, // 上传加载状态

      // 图片预览
      previewVisible: false,
      previewUrl: "",
    };
  },
  watch: {
    value: {
      handler(newVal) {
        if (newVal) {
          this.initImageData(newVal);
        } else {
          this.previewImages = [];
          this.uploadedUrls = [];
        }
      },
      immediate: true,
    },
  },
  created() {
    // 初始化数据
    if (this.value) {
      this.initImageData(this.value);
    }
  },

  mounted() {
    // 在组件挂载后确保文件输入引用正确
    this.fileInput = this.$refs.fileInput;
  },
  methods: {
    // 触发文件选择
    triggerUpload() {
      this.$refs.fileInput.click();
    },

    // 文件选择变化处理
    handleFileChange(e) {
      const files = e.target.files;
      if (!files.length) return;

      // 检查文件数量限制
      if (this.multiple) {
        if (this.previewImages.length + files.length > this.maxCount) {
          ElMessage.warning(`最多只能上传${this.maxCount}张图片`);
          this.$refs.fileInput.value = "";
          return;
        }
      } else {
        // 单图模式只处理第一张图片
        if (files.length > 1) {
          ElMessage.warning("单图模式只能上传一张图片");
        }
      }

      // 处理文件
      for (let i = 0; i < files.length; i++) {
        const file = files[i];

        // 验证文件类型
        if (!this.validateFileType(file)) {
          ElMessage.error(`文件 ${file.name} 类型不符合要求`);
          continue;
        }

        // 验证文件大小 (10MB限制)
        if (file.size > 10 * 1024 * 1024) {
          ElMessage.error(`文件 ${file.name} 大小超过10MB限制`);
          continue;
        }

        // 上传文件
        this.uploadFile(file);

        // 单图模式只处理第一张图片
        if (!this.multiple) break;
      }

      // 清空文件输入，以便再次选择同一文件
      this.$refs.fileInput.value = "";
    },

    // 验证文件类型
    validateFileType(file) {
      const acceptTypes = this.accept.split(",");
      return acceptTypes.includes(file.type);
    },

    // 上传文件
    async uploadFile(file) {
      const loading = ElLoading.service({
        lock: true,
        text: "上传中...",
        background: "rgba(255, 255, 255, 0.7)",
      });

      this.loading = true;

      try {
        // 调用上传API
        const { src } = await uploadFile(file, this.uploadUrl);

        // 这里根据实际API返回格式处理
        let fileUrl = src;

        if (fileUrl) {
          // 非多图模式先清空
          if (!this.multiple) {
            this.previewImages = [];
            this.uploadedUrls = [];
          }

          // 添加到预览列表和已上传URL列表
          this.previewImages.push(fileUrl);
          this.uploadedUrls.push(fileUrl);

          // 触发更新事件
          this.emitChange();
          ElMessage.success("上传成功");
        } else {
          ElMessage.error("上传失败：无法获取图片URL");
        }
      } catch (error) {
      } finally {
        this.loading = false;
        loading.close();
      }
    },

    // 移除图片
    removeImage(index) {
      this.previewImages.splice(index, 1);
      this.uploadedUrls.splice(index, 1);
      this.emitChange();
    },

    // 预览图片
    previewImage(url) {
      this.previewUrl = url;
      this.previewVisible = true;
    },

    // 触发变更事件
    emitChange() {
      const value = this.uploadedUrls.join(",");
      // this.$emit("update:value", value);
      this.$emit("ok", value);
    },

    // 初始化图片数据
    initImageData(value) {
      if (!value) return;

      try {
        const urls = value.split(",").filter((url) => url.trim());
        if (urls.length > 0) {
          this.previewImages = [...urls];
          this.uploadedUrls = [...urls];
        }
      } catch (error) {}
    },
  },
};
</script>

<style scoped lang="less">
/* 定义渐变 */
@primary-gradient: linear-gradient(135deg, #4b58dc, #7b86ff);
@danger-gradient: linear-gradient(135deg, #ff7b86, #dc4b58);

.cool-image-upload {
  width: 100%;

  .upload-container {
    width: 100%;
    margin-bottom: 16px;

    .image-list {
      display: flex;
      flex-wrap: wrap;
      gap: 16px;

      .image-item {
        position: relative;
        width: 120px;
        height: 120px;
        border-radius: 8px;
        overflow: hidden;
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
        transition: all 0.3s ease;

        &:hover {
          transform: translateY(-5px);
          box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);

          .image-actions {
            opacity: 1;
          }
        }

        .preview-image {
          width: 100%;
          height: 100%;
          object-fit: cover;
        }

        .image-actions {
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          background: rgba(0, 0, 0, 0.5);
          display: flex;
          justify-content: center;
          align-items: center;
          gap: 16px;
          opacity: 0;
          transition: opacity 0.3s ease;

          .action-btn {
            width: 36px;
            height: 36px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            transition: all 0.3s ease;

            &.view-btn {
              background: rgba(255, 255, 255, 0.2);
              color: white;

              &:hover {
                background: rgba(255, 255, 255, 0.4);
              }
            }

            &.delete-btn {
              background: rgba(220, 75, 88, 0.2);
              color: white;

              &:hover {
                background: rgba(220, 75, 88, 0.4);
              }
            }

            .iconfont {
              font-size: 18px;
            }
          }
        }

        &.add-more {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          background: rgba(75, 88, 220, 0.05);
          border: 2px dashed rgba(75, 88, 220, 0.2);
          cursor: pointer;
          transition: all 0.3s ease;

          &:hover {
            background: rgba(75, 88, 220, 0.1);
            border-color: rgba(75, 88, 220, 0.3);
          }

          .add-icon {
            font-size: 32px;
            line-height: 1;
            color: #4b58dc;
            margin-bottom: 8px;
          }

          .add-text {
            color: #4b58dc;
            font-size: 14px;
          }
        }
      }
    }

    .upload-area {
      width: 100%;
      height: 200px;
      border: 2px dashed rgba(75, 88, 220, 0.2);
      border-radius: 8px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      transition: all 0.3s ease;
      background: rgba(75, 88, 220, 0.02);

      &:hover {
        background: rgba(75, 88, 220, 0.05);
        border-color: rgba(75, 88, 220, 0.3);
      }

      .icon-tupian {
        font-size: 48px;
        color: #4b58dc;
        margin-bottom: 16px;
      }

      .upload-text {
        color: #333;
        text-align: center;

        .upload-tip {
          margin-top: 8px;
          font-size: 12px;
          color: #999;
        }
      }
    }
  }

  .preview-container {
    width: 100%;
    text-align: center;
    padding: 16px;
    box-sizing: border-box;

    .preview-large-image {
      max-width: 100%;
      max-height: 500px;
      border-radius: 4px;
    }
  }
}
</style>
